Skip to content

fix(DX-10060): retry transient network errors to prevent build crashes - #385

Merged
OMpawar-21 merged 8 commits into
developmentfrom
fix/DX-10060
Aug 6, 2026
Merged

fix(DX-10060): retry transient network errors to prevent build crashes#385
OMpawar-21 merged 8 commits into
developmentfrom
fix/DX-10060

Conversation

@OMpawar-21

@OMpawar-21 OMpawar-21 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Transient network-layer errors (ENOTFOUND, ENETUNREACH, ECONNRESET, ECONNREFUSED, EAI_AGAIN, ETIMEDOUT, EHOSTUNREACH, ENETDOWN) are now retried using the SDK's configured retry policy instead of failing immediately.
  • A combinedRetryCondition composes any user-supplied retryCondition with the new default network-error check — the user condition runs first, the original config is never mutated.
  • If the user-supplied retryCondition throws, a warning is emitted via logHandler and the SDK falls back to default retry behaviour.
  • ECONNABORTED is intentionally excluded — @contentstack/core classifies it as a structured TIMEOUT error.
  • Version bumped 5.5.05.6.0 (minor — crux retry logic changed).

Test coverage

8 unit tests added covering: ENOTFOUND retry, ENETUNREACH/ETIMEDOUT (customer-reported codes), EAI_AGAIN, ECONNRESET composition with user retryCondition, ECONNABORTED exclusion, retryOnError: false, and retryLimit: 0.

🤖 Generated with Claude Code

OMpawar-21 and others added 2 commits July 31, 2026 16:39
Transient network-layer errors (ENOTFOUND, ENETUNREACH, ECONNRESET,
ECONNREFUSED, EAI_AGAIN, ETIMEDOUT, EHOSTUNREACH, ENETDOWN) now trigger
the SDK's configured retry policy instead of failing immediately.

A combinedRetryCondition composes the user-supplied retryCondition with
the new default network-error check. The user condition runs first; if it
throws, a warning is emitted via logHandler and the SDK falls back to the
default. The original config object is never mutated.

ECONNABORTED is excluded — @contentstack/core classifies it as a
structured TIMEOUT error and handles it separately.

Resolves: SF Case #00060601 (SentinelOne)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@OMpawar-21
OMpawar-21 requested a review from a team as a code owner August 3, 2026 05:17
@snyk-io

snyk-io Bot commented Aug 3, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Coverage report

St.
Category Percentage Covered / Total
🟢 Statements
98.9% (+0.01% 🔼)
993/1004
🟢 Branches
96.52% (+0.08% 🔼)
305/316
🟢 Functions
97.79% (+0.02% 🔼)
221/226
🟢 Lines
99.37% (+0.01% 🔼)
945/951

Test suite run success

720 tests passing in 36 suites.

Report generated by 🧪jest coverage report action from 3e4e178

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@OMpawar-21 OMpawar-21 self-assigned this Aug 3, 2026
@OMpawar-21
OMpawar-21 marked this pull request as draft August 3, 2026 05:47
netrajpatel
netrajpatel previously approved these changes Aug 3, 2026
…warnings

Lines 182 and 184 in contentstack.ts (the catch block and logHandler warn path)
were flagged uncovered by jest-coverage-report-action. Added test (g) which
exercises a retryCondition that throws, verifies the SDK falls back to default
retry behaviour, and asserts the warning is emitted via logHandler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Not ready to approve

There are correctness and consistency issues in the new retry helper/documentation and logging payload that should be addressed before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Adds default retry behavior for transient network-layer failures in the Delivery SDK by composing a new network-error retry check with any user-provided retryCondition, and documents/releases the change as a minor version bump.

Changes:

  • Composes a combinedRetryCondition in the stack client to retry common transient network error codes while preserving the original user retryCondition reference.
  • Adds a utility helper (isTransientNetworkError) + constant set of retryable network error codes.
  • Introduces unit tests covering the new retry behavior and updates version/changelog to 5.6.0.
File summaries
File Description
test/unit/network-error-retry.spec.ts Adds unit tests validating retries for specific transient network error codes and opt-out behaviors.
src/stack/contentstack.ts Composes retry behavior with user retryCondition and adds warning logging when user logic throws.
src/common/utils.ts Adds transient network error code set and helper used by the new retry logic.
package.json Bumps SDK version to 5.6.0.
CHANGELOG.md Documents the retry behavior change and release date for 5.6.0.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 3
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread src/stack/contentstack.ts Outdated
Comment thread src/stack/contentstack.ts
Comment thread src/common/utils.ts
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

…age gap

- Fix misleading comment: only the retryCondition composition avoids
  mutation; config.host is still mutated elsewhere in the function
- Emit a structured logHandler payload ({ type, message, error }) when
  retryCondition throws, consistent with request/response interceptors
- Add !error.response guard to isTransientNetworkError so it only retries
  errors that arrived before any HTTP response, matching the JSDoc contract
- Add tests (h1, h, k) to cover the ?? fallback branch, the logHandler?.
  undefined branch, and the user retryCondition returning true; branch
  coverage on contentstack.ts: 93.88% → 97.95%

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The CHANGELOG entry is missing its release date and the new utils JSDoc text has inaccuracies that should be corrected before merging/releasing.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details

Suppressed comments (3)

CHANGELOG.md:2

  • The Version 5.6.0 changelog entry leaves the Date field blank, but other entries consistently include a formatted date (e.g. "#### Date: Aug-03-2026"). Please fill this in so releases are traceable.
#### Date:

src/common/utils.ts:41

  • The @returns description only mentions matching error.code, but the implementation also requires that there is no HTTP response (!error.response). Updating the JSDoc will keep the contract accurate for readers.
 * @returns {boolean} True if `error.code` matches a known transient network error code

src/common/utils.ts:39

  • This JSDoc sentence is grammatically inverted: it currently reads as if the caller would not be retried ("instead of being silently retried"), which contradicts the function’s purpose and the PR description. Reword so it clearly states the error is retried rather than failing immediately.
 * Determines whether an error represents a transient, retryable network-layer
 * failure (e.g. DNS lookup failure, connection reset), used to build the SDK's
 * default retry behavior so a single blip doesn't crash the caller (e.g. a
 * Next.js static build) instead of being silently retried.
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

OMpawar-21 and others added 2 commits August 5, 2026 15:21
…oc accuracy

- Add release date (Aug-05-2026) to the 5.6.0 CHANGELOG entry
- Update @returns JSDoc on isTransientNetworkError to reflect both
  conditions: error.code match and absence of error.response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 0 0 25 ✅ Passed
🟡 Medium Severity 0 0 500 ✅ Passed
🔵 Low Severity 0 0 1000 ✅ Passed

⏱️ SLA Breach Summary

✅ No SLA breaches detected. All vulnerabilities are within acceptable time thresholds.

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 0 30 / 120 days ✅ Passed
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

✅ BUILD PASSED - All security checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The changelog entry contains a future release date and wording that conflicts with earlier changelog notes, and the new JSDoc text in utils is currently misleading.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Review details

Suppressed comments (2)

CHANGELOG.md:4

  • The 5.6.0 changelog text reads like transient network errors are being retried for the first time, but 5.5.1 already documents default retry of transient network-level errors. Consider rewording this entry to clarify what specifically changed in 5.6.0 (e.g., composition with user-supplied retryCondition / behavior when retryCondition is present).
Fix: Transient network-layer errors (ENOTFOUND, ENETUNREACH, ECONNRESET, ECONNREFUSED, EAI_AGAIN, ETIMEDOUT, EHOSTUNREACH, ENETDOWN) are now retried automatically using the SDK's configured retry policy instead of failing immediately.
Enhancement: User-supplied `retryCondition` is composed with the default network-error retry logic — both are honoured without either replacing the other. If `retryCondition` throws, the SDK logs a warning via `logHandler` and falls back to default retry behaviour.

src/common/utils.ts:42

  • This JSDoc sentence is currently confusing: it implies the caller crashes "instead of being silently retried", but this helper exists to enable retries. Reword to reflect that transient network failures are retried according to policy to avoid crashing callers (e.g., build steps).
 * Determines whether an error represents a transient, retryable network-layer
 * failure (e.g. DNS lookup failure, connection reset), used to build the SDK's
 * default retry behavior so a single blip doesn't crash the caller (e.g. a
 * Next.js static build) instead of being silently retried.
 * @param {any} error - The error thrown by the underlying HTTP client (Axios)
 * @returns {boolean} True if `error.code` matches a known transient network error code and no HTTP response was received (`error.response` is absent)
 */
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@cs-raj
cs-raj marked this pull request as ready for review August 6, 2026 07:24
@OMpawar-21
OMpawar-21 merged commit 4d3344a into development Aug 6, 2026
11 checks passed
@OMpawar-21
OMpawar-21 deleted the fix/DX-10060 branch August 6, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants